import { PenChildProps } from "@/types";
import { useEffect, useState } from "react";
import {
  Button,
  ColorPicker,
  Input,
  InputNumber,
  Select,
  Slider,
  Space,
  Switch,
} from "antd";
import { FormRowCol } from "@/components/common/FormRowCol.tsx";
import { BindId } from "@meta2d/core/src/pen/model";
import { DeleteOutlined, EditOutlined, LinkOutlined } from "@ant-design/icons";
import { deepClone, Pen } from "@meta2d/core";
import { ReactAceEditor } from "@/components/common/ReactAceEditor.tsx";
import { AddPenData } from "@/components/Configuration/PenProps/components/DataPenType.tsx";
import { BindVariable } from "@/components/Configuration/PenProps/components/custom/BindVariable.tsx";

export interface DataPenType {
  name?: string;
  language?: string;
  placeholder?: string;
  type?: string;
  title?: string;
  key: keyof Pen;
  isNotString?: boolean;
  min?: number;
  max?: number;
  step?: number;
  precision?: number;
  options?: { label: string; value: string }[];
  dataIds?: BindId;
}

export function DataPen({ penOptions, setPenValue }: PenChildProps) {
  const [form, setForm] = useState<DataPenType[]>(
    (penOptions.form as DataPenType[]) || [],
  );
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [formItem, setFormItem] = useState<DataPenType>({
    key: "text",
    name: "",
    type: "text",
    placeholder: "",
    isNotString: true,
    language: "json",
    title: "json",
    min: undefined,
    max: undefined,
    step: undefined,
    precision: undefined,
    options: undefined,
  });
  const [openType, setOpenType] = useState(true);
  const [openIndex, setOpenIndex] = useState(-1);
  const [codeEditor, setCodeEditor] = useState<{
    show: boolean;
    key: keyof Pen;
    code: string;
  }>({
    show: false,
    key: "",
    code: "",
  });
  const [showBindVar, setShowBindVar] = useState(false);
  const onChange = (key: keyof typeof formItem, value: string | number) => {
    setFormItem({
      ...formItem,
      [key]: value,
    });
  };
  const handleAdd = () => {
    setIsModalOpen(true);
    setOpenType(false);
    setFormItem(() => {
      return {
        key: "text",
        name: "",
        type: "text",
        placeholder: "",
        isNotString: true,
        language: "json",
        title: "json",
        min: undefined,
        max: undefined,
        step: undefined,
        precision: undefined,
        options: undefined,
      };
    });
  };

  const addFormItem = () => {
    if (openType) {
      let newForm = deepClone(form);
      newForm[openIndex] = formItem;
      setForm(() => {
        return newForm;
      });
      setPenValue("form", newForm);
    } else {
      setForm(() => {
        return [...form, formItem];
      });
      setPenValue("form", [...form, formItem]);
    }
    setIsModalOpen(false);
  };
  useEffect(() => {
    // setPenValue("form", form);
    setForm(() => {
      return (penOptions.form as DataPenType[]) || [];
    });
  }, [penOptions]);
  const handleDel = (index: number) => {
    let newForm = deepClone(form);
    newForm.splice(index, 1);
    setForm(() => {
      return newForm;
    });
    setPenValue("form", newForm);
  };
  const handleEdit = (item: DataPenType, index: number) => {
    setFormItem(() => item);
    setOpenType(true);
    setOpenIndex(index);
    setIsModalOpen(true);
  };
  const handleBindVar = (item: DataPenType, index: number) => {
    setFormItem(() => item);
    setShowBindVar(true);
    setOpenIndex(index);
  };
  const handleSetVar = (data: {
    index: number;
    name: string;
    dataId: string;
    [key: string]: any;
  }) => {
    let newForm = deepClone(form);
    newForm[data.index] = {
      ...formItem,
      dataIds: data,
    };
    setForm(() => {
      return newForm;
    });
    setPenValue("form", newForm);
    setShowBindVar(false);
  };
  const handleUnBindVar = (index: number) => {
    let newForm = deepClone(penOptions.form || []);
    newForm[index] = {
      ...newForm[index],
      dataIds: {
        name: "",
        dataId: "",
      },
    };
    setPenValue("form", newForm);
  };
  return (
    <>
      <Space
        style={{ padding: "10px" }}
        className={"w-full"}
        direction="vertical"
      >
        {form.map((item, index) => {
          return (
            <div key={"dataItem" + index}>
              <FormRowCol
                label={item.name || ""}
                key={"type_" + item.key + index}
                labelSpan={6}
                valueSpan={18}
              >
                <Space>
                  {item.type == "text" && (
                    <Input
                      placeholder={item.placeholder}
                      style={{ width: 102 }}
                      value={penOptions[item.key]}
                      onChange={(e) =>
                        setPenValue(item.key as keyof Pen, e.target.value)
                      }
                    ></Input>
                  )}
                  {item.type == "textarea" && (
                    <Input.TextArea
                      placeholder={item.placeholder}
                      style={{ width: 102 }}
                      value={penOptions[item.key]}
                      onChange={(e) =>
                        setPenValue(item.key as keyof Pen, e.target.value)
                      }
                    ></Input.TextArea>
                  )}
                  {item.type == "number" && (
                    <InputNumber
                      placeholder={item.placeholder}
                      min={item.min}
                      max={item.max}
                      step={item.step}
                      precision={item.precision}
                      style={{ width: 102 }}
                      value={penOptions[item.key]}
                      onChange={(value) => {
                        setPenValue(item.key as keyof Pen, value);
                      }}
                    ></InputNumber>
                  )}
                  {item.type == "color" && (
                    <ColorPicker
                      value={penOptions[item.key]}
                      showText
                      style={{ width: 102 }}
                      onChange={(_, hex) => {
                        setPenValue(item.key as keyof Pen, hex);
                      }}
                    />
                  )}
                  {item.type == "select" && (
                    <Select
                      value={penOptions[item.key]}
                      style={{ width: 102 }}
                      placeholder={item.placeholder}
                      onChange={(value) => {
                        setPenValue(item.key as keyof Pen, value);
                      }}
                      options={item.options || []}
                    />
                  )}
                  {item.type == "switch" && (
                    <div style={{ width: 102 }}>
                      <Switch
                        checkedChildren="开启"
                        unCheckedChildren="关闭"
                        checked={penOptions[item.key]}
                        onChange={(value) => {
                          setPenValue(item.key as keyof Pen, value);
                        }}
                      />
                    </div>
                  )}
                  {item.type == "code" && (
                    <div style={{ width: 102 }}>
                      <Button
                        block
                        onClick={() => {
                          setCodeEditor(() => {
                            return {
                              show: true,
                              key: item.key,
                              code: JSON.stringify(penOptions[item.key]),
                            };
                          });
                        }}
                      >
                        配 置
                      </Button>
                    </div>
                  )}
                  {item.type == "slider" && (
                    <div style={{ width: 102 }}>
                      <Slider
                        min={item.min}
                        max={item.max}
                        step={item.step}
                        value={penOptions[item.key]}
                        onChange={(value) => {
                          setPenValue(item.key as keyof Pen, value);
                        }}
                      />
                    </div>
                  )}

                  <LinkOutlined onClick={() => handleBindVar(item, index)} />

                  <EditOutlined onClick={() => handleEdit(item, index)} />
                  <DeleteOutlined onClick={() => handleDel(index)} />
                </Space>
              </FormRowCol>
              {item.dataIds?.name && (
                <FormRowCol
                  label={""}
                  key={"prop_" + item.key + index}
                  labelSpan={6}
                  valueSpan={18}
                >
                  <Space>
                    <Input
                      bordered={false}
                      style={{
                        fontSize: 12,
                        paddingLeft: 0,
                        marginTop: 5,
                      }}
                      value={item.dataIds ? item.dataIds.name : ""}
                    ></Input>
                    <DeleteOutlined
                      style={{ cursor: "pointer" }}
                      onClick={() => handleUnBindVar(index)}
                    />
                  </Space>
                </FormRowCol>
              )}
            </div>
          );
        })}
      </Space>

      <div style={{ padding: 10 }}>
        <Button block type={"primary"} onClick={handleAdd}>
          添加数据
        </Button>
      </div>
      <AddPenData
        value={formItem}
        onChange={onChange}
        open={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        onOk={addFormItem}
      />

      <ReactAceEditor
        open={codeEditor.show}
        onCancel={() => {
          setCodeEditor({
            show: false,
            key: "",
            code: "",
          });
        }}
        onOk={(codeText) => {
          setPenValue(codeEditor.key as keyof Pen, JSON.parse(codeText));
          setCodeEditor({
            show: false,
            key: "",
            code: "",
          });
        }}
        value={codeEditor.code}
      ></ReactAceEditor>
      {/*定制化绑定变量组件：设备属性*/}
      {/*value:当前编辑的数据下标，open：是否显示弹窗*，onCancel：弹窗点击取消，onOk：弹窗点击确定*/}
      <BindVariable
        value={openIndex}
        open={showBindVar}
        onCancel={() => setShowBindVar(false)}
        onOk={handleSetVar}
      />
    </>
  );
}
